use itrustee_attester::attester::{ITrusteePlugin, RaBufferData};
use plugin_manager::{AgentPlugin, CollectEvidenceParams, QueryConfigurationFn};
use std::ffi::c_uint;

const TEST_UUID: &str = "4f84c0e0-4c3f-422f-97dc-14bfa2314ad1";
const TEST_WRONG_UUID: &str = "4f84c0e0-4c3f-422f-97dc-xxx";

fn mock_query_configuration_success(plugin_type: String) -> Option<String> {
    if plugin_type == "itrustee" {
        Some(get_valid_config_json())
    } else {
        None
    }
}

fn get_valid_config_json() -> String {
    format!(
        r#"{{
        "uuid": "{}"
    }}"#,
        TEST_UUID
    )
}

// Provide a mock implementation with the same name to override external symbols
#[cfg(test)]
#[no_mangle]
unsafe extern "C" fn RemoteAttest(_input: *mut RaBufferData, _out: *mut RaBufferData) -> c_uint {
    1
}

/// Test evidence collection without nonce (should use default)
#[test]
fn test_collect_evidence_without_nonce() {
    let plugin_type = "itrustee".to_string();
    let query_fn: QueryConfigurationFn = mock_query_configuration_success;

    let plugin = ITrusteePlugin::new(plugin_type, query_fn).expect("Should create plugin successfully");

    let evidence_params = CollectEvidenceParams {
        node_id: Some("test_node".to_string()),
        nonce: None, // No nonce provided
        log_types: None,
        attester_ids: Some(vec![TEST_UUID.to_string()]),
    };

    let res = plugin.collect_evidence(evidence_params);
    assert!(res.is_err(), "Should fail without nonce");
}

/// Test evidence collection with invalid UUID
#[test]
fn test_collect_evidence_invalid_uuid() {
    let plugin_type = "itrustee".to_string();
    let query_fn: QueryConfigurationFn = mock_query_configuration_success;

    let plugin = ITrusteePlugin::new(plugin_type, query_fn).expect("Should create plugin successfully");

    let evidence_params = CollectEvidenceParams {
        node_id: Some("test_node".to_string()),
        nonce: None,
        log_types: None,
        attester_ids: Some(vec![TEST_WRONG_UUID.to_string()]),
    };

    let result = plugin.collect_evidence(evidence_params);
    assert!(result.is_err(), "Should fail with invalid UUID format");
}

/// Test evidence collection with attester_ids empty
#[test]
fn test_collect_evidence_with_empty_attester_ids() {
    let plugin_type = "itrustee".to_string();
    let query_fn: QueryConfigurationFn = mock_query_configuration_success;

    let plugin = ITrusteePlugin::new(plugin_type, query_fn).expect("Should create plugin successfully");

    let evidence_params = CollectEvidenceParams {
        node_id: Some("test_node".to_string()),
        nonce: None,
        log_types: None,
        attester_ids: Some(Vec::<String>::new()), // Empty attester_ids
    };

    let result = plugin.collect_evidence(evidence_params);
    assert!(result.is_err(), "Should fail with empty attester_ids");
}

/// Test evidence collection with no attester_ids provided
#[test]
fn test_collect_evidence_no_attester_ids() {
    let plugin_type = "itrustee".to_string();
    let query_fn: QueryConfigurationFn = mock_query_configuration_success;

    let plugin = ITrusteePlugin::new(plugin_type, query_fn).expect("Should create plugin successfully");

    let evidence_params = CollectEvidenceParams {
        node_id: Some("test_node".to_string()),
        nonce: None,
        log_types: None,
        attester_ids: None, // No attester_ids provided
    };

    let result = plugin.collect_evidence(evidence_params);
    assert!(result.is_err(), "Should fail without attester_ids");
}

/// Test mock_remote_attest_failure function
#[test]
fn test_mock_remote_attest_failure() {
    let plugin_type = "itrustee".to_string();
    let query_fn: QueryConfigurationFn = mock_query_configuration_success;
    let plugin = ITrusteePlugin::new(plugin_type, query_fn).expect("Should create plugin successfully");
    let res = plugin.collect_evidence(CollectEvidenceParams {
        node_id: Some("test_node".to_string()),
        nonce: None,
        log_types: None,
        attester_ids: Some(vec![TEST_UUID.to_string()]),
    });
    assert!(res.is_err(), "Should fail when RemoteAttest returns non-zero due to abnormal itrustee environment");
}
